package com.zenithmind.common.config;

import com.zenithmind.common.security.DefaultSecurityRuleLoader;
import com.zenithmind.common.security.DynamicSecurityFilter;
import com.zenithmind.common.security.SecurityRuleLoader;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * 通用动态安全配置
 * 各个服务可以继承此类实现自己的安全配置
 * 
 * 只有在没有自定义安全配置时才会激活该配置
 * 通过zenithmind.security.dynamic.enabled属性控制是否启用
 */
@Slf4j
@Configuration
@EnableWebSecurity
@ConditionalOnProperty(name = "zenithmind.security.dynamic.enabled", havingValue = "true", matchIfMissing = false)
public class DynamicSecurityConfig {

    @Value("${spring.application.name}")
    private String applicationName;

    /**
     * 提供默认的安全规则加载器
     * 当没有自定义的SecurityRuleLoader实现时使用
     */
    @Bean
    @ConditionalOnMissingBean(SecurityRuleLoader.class)
    public SecurityRuleLoader defaultSecurityRuleLoader() {
        log.info("创建默认安全规则加载器: {}", applicationName);
        return new DefaultSecurityRuleLoader();
    }

    /**
     * 动态安全过滤器
     */
    @Bean
    public DynamicSecurityFilter dynamicSecurityFilter(SecurityRuleLoader securityRuleLoader) {
        log.info("创建动态安全过滤器: {}", applicationName);
        return new DynamicSecurityFilter(securityRuleLoader);
    }

    /**
     * 动态安全过滤器链配置
     * 使用不同的bean名称，避免与特定服务的安全配置冲突
     * 
     * @param http HttpSecurity对象
     * @param securityRuleLoader 安全规则加载器
     * @return SecurityFilterChain
     * @throws Exception 配置异常
     */
    @Bean(name = "dynamicSecurityFilterChain")
    @ConditionalOnMissingBean(name = "securityFilterChain")
    @Order(100) // 设置较低的优先级，让特定服务的配置优先生效
    public SecurityFilterChain dynamicSecurityFilterChain(HttpSecurity http, SecurityRuleLoader securityRuleLoader) throws Exception {
        log.info("初始化动态安全配置: {}", applicationName);
        
        // 禁用CSRF，使用无状态会话
        http.csrf().disable()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // 添加动态安全过滤器
        http.addFilterBefore(new DynamicSecurityFilter(securityRuleLoader), 
                              UsernamePasswordAuthenticationFilter.class);
        
        // 根据各服务特性，实现自定义配置
        configureHttpSecurity(http);

        return http.build();
    }

    /**
     * 自定义HTTP安全配置
     * 子类可以重写此方法实现特定的安全配置
     *
     * @param http HttpSecurity对象
     * @throws Exception 配置异常
     */
    protected void configureHttpSecurity(HttpSecurity http) throws Exception {
        // 默认实现不做任何操作
        // 子类可以根据需要重写此方法
    }
} 